package com.apache.flow.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;
import oracle.sql.CLOB;

import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.hibernate.engine.jdbc.SerializableClobProxy;
import org.jbpm.api.Execution;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.HistoryService;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.TaskQuery;
import org.jbpm.api.TaskService;
import org.jbpm.api.history.HistoryProcessInstanceQuery;
import org.jbpm.api.model.ActivityCoordinates;
import org.jbpm.api.task.Participation;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.env.EnvironmentFactory;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
import org.jbpm.pvm.internal.model.TransitionImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.apache.common.FlowBaseAction;
import com.apache.common.Native2AsciiUtils;
import com.apache.core.orm.Page;
import com.apache.core.utils.web.struts2.Struts2Utils;
import com.apache.flow.core.entity.FlowAutomaticProcessing;
import com.apache.flow.core.entity.FlowHistroy;
import com.apache.flow.core.manager.FlowAutomaticProcessingManager;
import com.apache.flow.core.manager.FlowDeployManager;
import com.apache.flow.core.manager.FlowHistoryManager;
import com.apache.flow.taskHandler.ProcessInsOP;
import com.apache.flow.taskHandler.TaskTag;
import com.apache.flow.taskHandler.ZbxTask;
import com.apache.flow.timer.AutoTaskTimer;
import com.apache.flow.vo.HistTaskVo;
import com.apache.flow.vo.TaskVo;
import com.apache.tools.DateUtils;
import com.apache.tools.StrUtil;

@Namespace("/flow/core")
@Results({ @Result(name = "init", location = "flow-deploy.action", type = "redirect"),
		@Result(name = "approve", location = "flow-approve.action", type = "redirect") })
@SuppressWarnings("all")
public class FlowWebserviceAction extends FlowBaseAction {
	/**
	 * 日志
	 */
	private Logger logger = LoggerFactory.getLogger(FlowWebserviceAction.class);
	private static final long serialVersionUID = 1L;
	@Autowired
	private ProcessEngine processEngine;
	private FlowDeployManager flowDeployManager;
	private FlowHistoryManager flowHistoryManager;
	private FlowAutomaticProcessingManager automaticProcessingManager;

	/**
	 * 活动节点坐标
	 */
	private ActivityCoordinates ac;
	/**
	 * 流程实例id
	 */
	private String processInsId;
	private String taskId;
	private String result;
	private String agentUserId;
	private String definitionId;
	private String lastUser;
	private String nextUsers;
	private String op;
	private String startNode;//起始节点
	private String sourceNode;//目标节点
	private String findNodeName;//

	private String proId;

	/**
	 * 
	 * @return
	 * @throws IOException
	 * <p>@description 流程审核方法
	 * <p>@version 1.0
	 * <p>@author lvcai
	 * <p>@update 2013-7-29 下午06:06:36
	 */
	public String approve() throws IOException {
		logger.info("流程审核方法开始执行");
		String returnResult = null;
		String errmsg = null;
		String instFlag = "F";

		Map<String, String> variables = new HashMap<String, String>();
		Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
		while (names.hasMoreElements()) {
			String key = names.nextElement();
			if (null != key && !"".equals(key)) {
				String value = Struts2Utils.getRequest().getParameter(key);
				variables.put(key, java.net.URLDecoder.decode(value, "UTF-8"));
			}
		}
		String executeTime = variables.get("executeTime");//---
		if (StrUtil.isNull(executeTime))
			executeTime = "";//---
		String taskId = variables.get("taskId");
		String result = variables.get("result");
		String proId = variables.get("proId");
		logger.info("流程审核：获取到taskId=" + taskId + "  result=" + result + "  proId=" + proId);
		String taskName = "";
		if (null != taskId && !"".equals(taskId) && null != result && !"".equals(result)) {
			try {
				TaskService taskService = processEngine.getTaskService();
				Task task = taskService.getTask(taskId);

				if (task != null) {
					taskName = task.getName();//2016-02-24

					String exeId = task.getExecutionId();
					ExecutionService executionService = processEngine.getExecutionService();
					Execution execution = executionService.findExecutionById(exeId);
					executionService.setVariable(exeId, "executeTime", executeTime);//---
					Execution processInstance = execution.getProcessInstance();
					String processInstanceId = processInstance.getId();

					ZbxTask sign = new ZbxTask(task, variables);
					processEngine.execute(sign);

					HistoryService historyService = processEngine.getHistoryService();
					HistoryProcessInstanceQuery historyProcessInstanceQuery = historyService
							.createHistoryProcessInstanceQuery();
					if ("ended".equals(historyProcessInstanceQuery.processInstanceId(processInstanceId).list().get(0)
							.getState())) {
						instFlag = "T";//流程结束
					}
					returnResult = "T";
					errmsg = "流程审核成功";
				} else {
					returnResult = "F";
					errmsg = "没有找到任务Id为" + taskId + "的任务";
				}

			} catch (org.jbpm.api.JbpmException e) {
				//流程定义返回错误信息
				returnResult = "F";
				if (e.getMessage().contains("没有找到用户")) {
					errmsg = "下一任务节点没有执行用户";
					Struts2Utils.getRequest().setAttribute("info", "下个任务节点未找到任务执行者");
				} else if (e.getMessage().contains("suspended")) {
					errmsg = "该流程已挂起";
					Struts2Utils.getRequest().setAttribute("info", "该流程已挂起");
				} else {
					errmsg = "流程审核时发送未知异常";
				}
				e.printStackTrace();
			} catch (Exception e) {
				returnResult = "F";
				errmsg = "流程审核时发送未知异常";
				e.printStackTrace();
			}
		} else {
			returnResult = "F";
			errmsg = "参数taskId或result参数未传递";
		}

		String xml = this.getXmlInfo(returnResult, errmsg, instFlag);
		logger.info("审核节点【" + taskName + "】,流程审核发送给业务系统的报文为" + xml);
		this.outputXml(xml, Struts2Utils.getResponse());

		return null;
	}

	private String getXmlInfo(String result, String errmsg, String instFlag) {
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg><instFlag>" + instFlag
				+ "</instFlag>");
		XmlStr.append("</root>");
		return XmlStr.toString();
	}

	/**
	 * 待办任务
	 * @throws Exception 
	 */
	public String approveData() throws Exception {
		logger.info("获取待办任务方法开始 ");
		String result = null;
		String errmsg = null;
		String xml = null;
		Map<String, String> variables = new HashMap<String, String>();
		Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
		logger.info("获取待办任务遍历参数开始 ");
		while (names.hasMoreElements()) {
			String key = names.nextElement();
			if (!"httpRand".equals(key)) {//过滤掉时间参数
				String v = Struts2Utils.getRequest().getParameter(key);
				String value = (null == v) ? "" : java.net.URLDecoder.decode(v, "UTF-8");
				logger.info(key + "     " + value);
				variables.put(key, value);
			}
		}
		logger.info("获取待办任务遍历参数结束 ");
		String assignee = variables.get("assignee");
		if (!StrUtil.isNull(assignee)) {
			assignee = Native2AsciiUtils.getInstance().ascii2Native(assignee);
		}

		String page = variables.get("pageNo");
		String rows = variables.get("pageSize");

		TaskService taskService = processEngine.getTaskService();
		if (assignee != null) {
			TaskQuery taskQuery = taskService.createTaskQuery();
			int sumCount = taskQuery.assignee(assignee).list().size();
			List<Task> taskList = null;
			if (page != null && !"".equals(page) && rows != null && !"".equals(rows)) {
				try {
					int pageNo = Integer.valueOf(page);
					int pageSize = Integer.valueOf(rows);
					int startIndex = (pageNo - 1) * pageSize;
					logger.info("分页查询待办任务   assignee=" + assignee + "   pageNo=" + pageNo + "    pageSize=" + pageSize);
					taskList = taskQuery.assignee(assignee).notSuspended().page(startIndex, pageSize)
							.orderDesc(TaskQuery.PROPERTY_CREATEDATE).list();
				} catch (java.lang.NumberFormatException e) {
					result = "F";
					errmsg = "参数pageNo、pageSize必须为正整数";
					xml = getXmlDateList(result, errmsg, null, 0);
					this.outputXml(xml, Struts2Utils.getResponse());
					return null;
				}
			} else {
				logger.info("查询所有待办任务   assignee=" + assignee);
				taskList = taskQuery.assignee(assignee).notSuspended().orderDesc(TaskQuery.PROPERTY_CREATEDATE).list();
			}
			logger.info("待办任务结果集个数>" + taskList.size());
			if (null != taskList && taskList.size() > 0) {
				List<TaskVo> taskVoList = new ArrayList<TaskVo>();
				String description = null;
				String[] strs = null;
				for (Task task : taskList) {
					TaskVo taskVo = new TaskVo();
					taskVo.setId(task.getId());
					taskVo.setName(task.getName());
					taskVo.setFormResourceName(task.getFormResourceName());
					taskVo.setProcessInstanceId(getInstIdFromExeId(task.getExecutionId()));
					taskVo.setCreateTime(DateUtils.format(task.getCreateTime(),
							DateUtils.FmtStr.yyyyMMdd_HHmmss.toString()));

					description = task.getDescription();
					strs = description.split(TaskTag.splitTag, -1);
					taskVo.setEndTime(StrUtil.doNull(strs[0], ""));
					taskVo.setFormId(StrUtil.doNull(strs[1], ""));
					taskVo.setFormName(StrUtil.doNull(strs[2], ""));
					taskVo.setFormInfo(StrUtil.doNull(strs[3], ""));
					taskVo.setFormType(StrUtil.doNull(strs[4], ""));
					taskVo.setLastUser(StrUtil.doNull(strs[5], ""));
					taskVo.setUserName(StrUtil.doNull(strs[6], ""));
					taskVo.setSysEname(StrUtil.doNull(strs[7], ""));
					taskVo.setProId(StrUtil.doNull(strs[8], ""));
					taskVo.setProNo(StrUtil.doNull(strs[9], ""));
					taskVo.setProName(StrUtil.doNull(strs[10], ""));
					taskVoList.add(taskVo);
				}
				result = "T";
				errmsg = "获取待办任务成功";
				xml = getXmlDateList(result, errmsg, taskVoList, sumCount);
			} else {
				result = "T";
				errmsg = "获取待办任务成功";
				xml = getXmlDateList(result, errmsg, null, 0);
			}

		} else {
			result = "F";
			errmsg = "参数assignee为空";
			xml = getXmlDateList(result, errmsg, null, 0);
		}
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	/**
	 * 
	 * @return
	 * @throws Exception
	 * <p>@description 根据实例Id获取当前活动节点信息(processInsId)[不包括子任务]
	 * <p>@version 1.0
	 * <p>@author lvcai
	 * <p>@update 2013-8-1 下午08:38:52
	 */
	public String getActiveTaskInfo() throws Exception {
		logger.info("根据实例Id获取当前活动节点信息方法开始执行      参数processInsId=" + processInsId);
		String result = null;
		String errmsg = null;
		String xml = null;
		if (null != processInsId && !"".equals(processInsId)) {
			//管理流程实例
			ExecutionService executionService = processEngine.getExecutionService();
			//流程实例
			ProcessInstance processInstance = executionService.findProcessInstanceById(processInsId);
			if (null == processInstance) {
				result = "F";
				errmsg = "该流程实例不存在或者已结束";
				xml = getActiveTaskIdXml(result, errmsg, null);
				logger.error("processInsId=" + processInsId + "  该流程实例不存在");
			} else {
				if (processInstance.isEnded()) {//如果流程实例已经结束
					result = "F";
					errmsg = "该流程实例已经结束";
					xml = getActiveTaskIdXml(result, errmsg, null);
					logger.error("processInsId=" + processInsId + "  该流程实例已经结束");
				} else {
					TaskService taskService = processEngine.getTaskService();
					TaskQuery taskQuery = taskService.createTaskQuery();
					List<Task> taskList = taskQuery.processInstanceId(processInsId).list();
					List<TaskVo> vo_list = new ArrayList<TaskVo>();
					if (null != taskList && taskList.size() > 0) {
						for (Task task : taskList) {
							TaskVo vo = new TaskVo();
							vo.setId(task.getId());
							vo.setName(task.getName());
							vo_list.add(vo);

						}
					}
					result = "T";
					errmsg = "获取当前活动节点信息成功";
					xml = getActiveTaskIdXml(result, errmsg, vo_list);

				}
			}

		} else {
			result = "F";
			errmsg = "参数processInsId为空";
			xml = getActiveTaskIdXml(result, errmsg, null);
		}
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	/**
	 * description: 启动流程实例  修改(2015年4月16日18:07:07 yxcui)
	 * 				此类主要为了服务外部系统通过 http调用,启动流程实例 
	 * @return
	 * @throws IOException  
	 * @author xyc 
	 * @update 2015-4-16
	 */
	@Transactional
	public String start() throws IOException {
		logger.info("流程启动方法开始执行");
		//管理流程定义
		RepositoryService repositoryService = processEngine.getRepositoryService();
		Map<String, String> variables = new HashMap<String, String>();
		Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
		logger.info("流程启动时,业务系统传递参数为");
		//遍历业务参数
		while (names.hasMoreElements()) {
			String key = names.nextElement();
			if (!"httpRand".equals(key)) {//过滤掉时间参数
				String v = Struts2Utils.getRequest().getParameter(key);
				String value = (null == v) ? "" : java.net.URLDecoder.decode(v, "UTF-8");
				logger.info(key + "     " + value);
				variables.put(key, value);
			}
		}
		logger.info("流程启动时传递参数遍历结束");
		ExecutionService executionService = processEngine.getExecutionService();
		String xml = null;
		try {
			ProcessInstance processInstance = executionService.startProcessInstanceById(definitionId, variables);
			String processInstanceId = processInstance.getId();
			//如果指定了流程启动节点 则跳转到指定节点
			if (StrUtil.isNotNull(variables.get("firstNode"))) {
				//目标节点
				String sourceNode = StrUtil.doNull(variables.get("firstNode"), "");
				TaskService taskService = processEngine.getTaskService();
				TaskQuery taskQuery = taskService.createTaskQuery();
				List<Task> taskList = taskQuery.processInstanceId(processInstanceId).list();
				if (taskList == null && taskList.size() == 0) {
					xml = getResultXml("F", "未找到当前活动的Task任务", "");
				} else if (taskList.size() == 1) {
					String createTransitionName = "to " + sourceNode;
					Task activeTask = taskList.get(0);
					EnvironmentImpl envImpl = ((EnvironmentFactory) processEngine).openEnvironment();

					ExecutionImpl e = (ExecutionImpl) executionService.findExecutionById(activeTask.getExecutionId());
					ActivityImpl clerkOpinionActivityImpl = e.getActivity();

					ProcessDefinitionImpl processDefinitionImpl = clerkOpinionActivityImpl.getProcessDefinition();

					ActivityImpl applyActivityImpl = processDefinitionImpl.findActivity(sourceNode);
					//能够查询到目标节点
					if (applyActivityImpl != null) {
						TransitionImpl toApply = clerkOpinionActivityImpl.createOutgoingTransition();
						toApply.setSource(clerkOpinionActivityImpl);
						toApply.setDestination(applyActivityImpl);
						toApply.setName(createTransitionName);
						//跳向目标节点
						taskService.completeTask(activeTask.getId(), createTransitionName);
						xml = getResultXml("T", "启动流程成功", processInstanceId);
					} else {
						//目标节点不存在
						xml = getResultXml("F", "流程启动时指定的目标节点不存在", "");
					}
					if (envImpl != null) {
						envImpl.close();
					}
				} else {
					xml = getResultXml("F", "当前活动的Task个数大于1,暂不支持", "");
				}
			} else {
				xml = getResultXml("T", "启动流程成功", processInstanceId);
			}
		} catch (org.jbpm.api.JbpmException e) {
			if (e.getMessage().contains("is suspended")) {
				xml = getResultXml("F", "该流程已经挂起", "");
			} else if (e.getMessage().contains("no process definition with id")) {
				xml = getResultXml("F", "流程" + definitionId + "不存在，或者已经被删除", "");
			} else if (e.getMessage().contains("没有找到用户")) {
				xml = getResultXml("F", "流程启动时第一个节点未找到审核人", "");
			} else {
				xml = getResultXml("F", "发生未知错误", "");
			}
			e.printStackTrace();
		}
		logger.info("流程启动：返回给业务系统的报文信息为：" + xml);
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	/**
	 * 
	 * @param result
	 * @param errmsg
	 * @param processInstanceId
	 * @return
	 * <p>@description 获取返回报文xml
	 * <p>@version 1.0
	 * <p>@author lvcai
	 * <p>@update 2013-7-29 下午06:26:00
	 */
	private String getResultXml(String result, String errmsg, String processInstanceId) {
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg>");
		if (processInstanceId != null && !"".equals(processInstanceId)) {
			XmlStr.append("<processInstanceId>" + processInstanceId + "</processInstanceId>");
		}
		XmlStr.append("</root>");
		return XmlStr.toString();

	}

	/**
	 * 
	 * @return
	 * <p>@description 自处理任务结果反馈
	 * <p>@version 1.0
	 * <p>@author lvcai
	 * <p>@update 2013-7-29 下午06:25:26
	 */
	public String executeTask() {
		logger.info("自处理任务结果反馈开始执行,传递参数taskId=" + taskId + "   result=" + result);
		String xml = null;
		if (null != taskId && !"".equals(taskId) && null != result && !"".equals(result)) {
			try {
				TaskService taskService = processEngine.getTaskService();
				Task task = taskService.getTask(taskId);
				Map<String, String> variables = new HashMap<String, String>();
				variables.put("result", result);
				ZbxTask sign = new ZbxTask(task, variables);
				processEngine.execute(sign);
				xml = getAutoTaskXml("T", "自处理任务处理成功", taskId);
			} catch (Exception e) {
				e.printStackTrace();
				xml = getAutoTaskXml("F", "工作流系统发生未知异常", taskId);
			}
		} else {
			xml = getAutoTaskXml("F", "自处理任务失败，参数taskId或result为空", "");
		}
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	/**
	 * 
	 * @return
	 * @throws Exception
	 * <p>@description 综合查询待办列表
	 * <p>@version 1.0
	 * <p>@author lvcai
	 * <p>@update 2013-11-16 上午11:14:56
	 */
	public String findTasksByOptions() throws Exception {
		logger.info("综合查询待办列表开始 ");
		String result = null;
		String errmsg = null;
		String xml = null;
		Map<String, String> variables = new HashMap<String, String>();
		Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
		while (names.hasMoreElements()) {
			String key = names.nextElement();
			if (!"httpRand".equals(key)) {//过滤掉时间参数
				String v = Struts2Utils.getRequest().getParameter(key);
				String value = (null == v) ? "" : java.net.URLDecoder.decode(v, "UTF-8");
				variables.put(key, value);
			}
		}
		try {
			Page<Object[]> page = flowDeployManager.findTasksByOptions(variables);

			List<TaskVo> taskVoList = new ArrayList<TaskVo>();
			String description = null;
			String[] strs = null;
			for (Object[] objArry : page.getResult()) {
				TaskVo taskVo = new TaskVo();

				//2015年3月20日15:43:07  崔永旭更新  在mysql中不适用,因为oracle获取的objArry[5]为clob类型,而mysql获取的是textlong类型,故在此判断一下
				Object obj = objArry[5];
				StringBuffer sb = new StringBuffer(65535);// 64K 
				if (!(obj instanceof String)) {
					SerializableClobProxy proxy = (SerializableClobProxy) Proxy.getInvocationHandler(objArry[5]);
					oracle.sql.CLOB realClob = (CLOB) proxy.getWrappedClob();

					Reader clobStream = null;
					clobStream = realClob.getCharacterStream();
					char[] b = new char[60000];// 每次获取60K 
					int i = 0;
					while ((i = clobStream.read(b)) != -1) {
						sb.append(b, 0, i);
					}
				} else {
					sb = sb.append(obj);
				}

				taskVo.setId(StrUtil.doNull(objArry[0].toString(), ""));
				taskVo.setProcessInstanceId(StrUtil.doNull(objArry[1].toString(), ""));
				taskVo.setName(StrUtil.doNull(objArry[2].toString(), ""));
				taskVo.setFormResourceName(StrUtil.doNull(objArry[3].toString(), ""));
				taskVo.setAssignee(StrUtil.doNull(objArry[6].toString(), ""));
				taskVo.setCreateTime(StrUtil.doNull(objArry[4].toString(), ""));

				description = StrUtil.doNull(sb.toString(), "");
				strs = description.split(TaskTag.splitTag, -1);
				taskVo.setEndTime(StrUtil.doNull(strs[0], ""));
				taskVo.setFormId(StrUtil.doNull(strs[1], ""));
				taskVo.setFormName(StrUtil.doNull(strs[2], ""));
				taskVo.setFormInfo(StrUtil.doNull(strs[3], ""));
				taskVo.setFormType(StrUtil.doNull(strs[4], ""));
				taskVo.setLastUser(StrUtil.doNull(strs[5], ""));
				taskVo.setUserName(StrUtil.doNull(strs[6], ""));
				taskVo.setSysEname(StrUtil.doNull(strs[7], ""));
				taskVo.setProId(StrUtil.doNull(strs[8], ""));
				taskVo.setProNo(StrUtil.doNull(strs[9], ""));
				taskVo.setProName(StrUtil.doNull(strs[10], ""));
				taskVoList.add(taskVo);
			}
			result = "T";
			errmsg = "综合查询待办任务成功";
			xml = getXmlDateList(result, errmsg, taskVoList, (int) page.getTotalCount());
		} catch (Exception e) {
			result = "F";
			errmsg = "发生未知异常";
			xml = getXmlDateList(result, errmsg, null, 0);
			e.printStackTrace();
		}

		this.outputXml(xml, Struts2Utils.getResponse());
		return null;

	}

	private String getAutoTaskXml(String result, String errmsg, String taskId) {
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg>");
		XmlStr.append("<taskId>" + taskId + "</taskId>");
		XmlStr.append("</root>");
		return XmlStr.toString();

	}

	private String getActiveTaskIdXml(String result, String errmsg, List<TaskVo> taskVoList) {
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg>");
		XmlStr.append("<records totalRecord='" + (taskVoList == null ? 0 : taskVoList.size()) + "' >");

		if (null != taskVoList && taskVoList.size() > 0) {
			for (int i = 0; i < taskVoList.size(); i++) {
				TaskVo taskVo = (TaskVo) taskVoList.get(i);
				XmlStr.append("<record>");
				XmlStr.append("<taskId><![CDATA[" + StrUtil.doNull(taskVo.getId(), "") + "]]></taskId>");
				XmlStr.append("<taskName><![CDATA[" + StrUtil.doNull(taskVo.getName(), "") + "]]></taskName>");
				XmlStr.append("</record>");
			}
		}
		XmlStr.append("</records>");
		XmlStr.append("</root>");

		return XmlStr.toString();
	}

	private String getInstIdFromExeId(String temp) {
		String data = temp;
		int tt = data.indexOf('.');
		tt = data.indexOf('.', tt + 1);
		if (tt > 0) {
			data = data.substring(0, tt);
		}
		return data;
	}

	/**
	 * 代办任务
	 */
	public String agent() throws IOException {
		TaskService taskService = processEngine.getTaskService();
		try {
			if (taskId != null) {
				Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
				while (names.hasMoreElements()) {
					String key = names.nextElement();
					String v = Struts2Utils.getRequest().getParameter(key);
					if (key != null && key.equals("agentUserId")) {
						taskService.assignTask(taskId, v);
						break;
					}
				}
			}
			List lst = new ArrayList();
			lst.add("分配成功!");
			String xml = getAgentList(lst);
			this.outputXml(xml, Struts2Utils.getResponse());
		} catch (Exception e) {
			showError("分配失败!");
		}
		return null;
	}

	/**
	 * 
	 * @return
	 * @throws Exception
	 * <p>@description 根据实例Id操作流程实例
	 * <p>@version 1.0
	 * <p>@author lvcai
	 * <p>@update 2013-8-19 下午04:45:54
	 */
	public String processInsOP() throws Exception {
		logger.info("根据实例Id操作流程实例方法开始 ");
		String result = "F";
		String errmsg = "操作失败";
		if (StrUtil.isNotNull(processInsId)) {
			if (StrUtil.isNotNull(op)) {
				//结束流程等待状态 
				if ("4".equals(op.trim())) {
					this.overState();
					return null;
				}

				try {
					ProcessInsOP processInsOP = new ProcessInsOP(processInsId, op);
					String info = String.valueOf(processEngine.execute(processInsOP));
					if ("T".equals(info)) {
						result = "T";
						errmsg = "操作成功";
						logger.info("实例操作成功,实例Id为" + processInsId);
					} else {
						errmsg = info;
						logger.error("返回结果【" + info + "】,实例Id为" + processInsId);
					}

				} catch (Exception e) {
					e.printStackTrace();
					errmsg = "操作实例时发生未知异常";
					logger.error("操作实例时发生未知异常,实例Id为" + processInsId);
				}

			} else {
				errmsg = "参数op为空";
			}

		} else {
			errmsg = "参数processInsId为空";
		}
		String xml = getResultXml(result, errmsg, null);
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	public ActivityCoordinates getPicNode() throws IOException {
		//管理流程定义
		RepositoryService repositoryService = processEngine.getRepositoryService();
		//管理流程实例
		ExecutionService executionService = processEngine.getExecutionService();
		//流程实例
		ProcessInstance processInstance = executionService.findProcessInstanceById(processInsId);

		Set<String> activityNames = null;
		String xml = null;
		if (processInstance != null) {
			if ("suspended".equals(processInstance.getState())) {
				StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
				XmlStr.append("<result>F</result><errmsg>该流程实例已被挂起,返回流程图为流程定义图</errmsg>");
				XmlStr.append("</root>");
				xml = XmlStr.toString();
			} else {
				//活动节点名称
				activityNames = processInstance.findActiveActivityNames();
				//第一个活动节点
				String activityName = activityNames.iterator().next();
				ac = repositoryService.getActivityCoordinates(processInstance.getProcessDefinitionId(), activityName);
				xml = getPicNodeXml(ac);
			}

		} else {
			String errmsg = null;
			HistoryService historyService = processEngine.getHistoryService();
			HistoryProcessInstanceQuery historyProcessInstanceQuery = historyService
					.createHistoryProcessInstanceQuery();
			if ("ended".equals(historyProcessInstanceQuery.processInstanceId(processInsId).list().get(0).getState())) {
				errmsg = "该流程实例已结束,无法查看流程图";//流程实例结束
			}
			StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
			XmlStr.append("<result>F</result><errmsg>" + errmsg + "</errmsg>");
			XmlStr.append("</root>");
			xml = XmlStr.toString();
		}

		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	/**
	 * 获取要返回的xml数据
	 * @param list
	 * @return
	 */
	private String getPicNodeXml(ActivityCoordinates ac) {
		String result = "T";
		String errmsg = "正确";
		if (ac == null) {
			result = "F";
			errmsg = "没有获取到数据";
		}
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg>");
		XmlStr.append("<height>" + ac.getHeight() + "</height>");
		XmlStr.append("<width>" + ac.getWidth() + "</width>");
		XmlStr.append("<x>" + ac.getX() + "</x>");
		XmlStr.append("<y>" + ac.getY() + "</y>");
		XmlStr.append("</root>");

		return XmlStr.toString();
	}

	/**
	 * 获取实例当前节点name及节点任务执行人
	 */
	public void getPicNodeInfo() throws IOException {

		String jsoncallback = Struts2Utils.getRequest().getParameter("jsoncallback");
		String jb = StrUtil.doNull(jsoncallback);
		JSONObject json = new JSONObject();
		if (StrUtil.isNull(processInsId)) {
			json.put("message", "缺少必要的参数processInsId，实例id不能为空！");
			json.put("flag", "false");
			Struts2Utils.getResponse().getWriter().print(jb + "(" + json.toString() + ")");
			return;
		}

		RepositoryService repositoryService = processEngine.getRepositoryService();//管理流程定义
		ExecutionService executionService = processEngine.getExecutionService();//管理流程实例
		ProcessInstance processInstance = executionService.findProcessInstanceById(processInsId);//流程实例
		TaskService taskService = processEngine.getTaskService();

		Set<String> activityNames = null;
		if (processInstance != null) {
			if ("suspended".equals(processInstance.getState())) {
				json.put("message", "该流程实例已被挂起！");
				json.put("flag", "false");
			} else {
				activityNames = processInstance.findActiveActivityNames();//活动节点名称
				//第一个活动节点
				String activityName = activityNames.iterator().next();
				ac = repositoryService.getActivityCoordinates(processInstance.getProcessDefinitionId(), activityName);

				TaskQuery taskQuery = taskService.createTaskQuery();
				List<Task> taskList = taskQuery.processInstanceId(processInsId).list();
				List<Participation> participationList = taskService.getTaskParticipations(taskList.get(0).getId());

				String assignees = "";
				for (int i = 0; i < participationList.size(); i++) {
					assignees += participationList.get(i).getUserId();
					if (i < participationList.size() - 1) {
						assignees += ",";
					}
				}
				json.put("flag", "true");
				json.put("message", "获取实例当前节点名称及节点任务执行人成功！");
				json.put("activityName", activityName);
				json.put("assignees", assignees);
			}
		} else {
			HistoryService historyService = processEngine.getHistoryService();
			HistoryProcessInstanceQuery historyProcessInstanceQuery = historyService
					.createHistoryProcessInstanceQuery();
			if ("ended".equals(historyProcessInstanceQuery.processInstanceId(processInsId).list().get(0).getState())) {
				json.put("message", "该流程实例已结束！");
				json.put("flag", "false");
			}
			json.put("message", "该流程实例不存在！");
			json.put("flag", "false");
		}
		Struts2Utils.getResponse().getWriter().print(jb + "(" + json.toString() + ")");
	}

	/**
	 * 获取要返回的xml数据
	 * @param list
	 * @return
	 */
	private String getAgentList(List list) {
		String result = "T";
		String errmsg = "正确";
		if (list.size() <= 0) {
			result = "F";
			errmsg = "没有获取到数据";
		}
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg>");
		XmlStr.append("<records totalRecord='" + (list == null ? 0 : list.size()) + "' >");

		for (int i = 0; i < list.size(); i++) {
			String ss = (String) list.get(i);
			XmlStr.append("<record>");
			XmlStr.append("<respCode>" + ss + "</respCode>");
			XmlStr.append("</record>");
		}

		XmlStr.append("</records>");
		XmlStr.append("</root>");

		return XmlStr.toString();
	}

	/**
	 * description:  获取历史待办任务 没办法,以前这么写,我也是被逼的
	 * @param result
	 * @param errmsg
	 * @param list
	 * @param sumSize
	 * @return  
	 * @author xyc 
	 * @update 2015-4-14
	 */
	private String getXmlHistTaskList(String result, String errmsg, List list, Integer sumSize) {
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg><totalCount>" + sumSize
				+ "</totalCount>");
		XmlStr.append("<records totalRecord='" + (list == null ? 0 : list.size()) + "' >");

		if (null != list && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				HistTaskVo taskVo = (HistTaskVo) list.get(i);
				XmlStr.append("<record>");
				XmlStr.append("<procdefId><![CDATA[" + StrUtil.doNull(taskVo.getProcdefId(), "") + "]]></procdefId>");
				XmlStr.append("<executionId><![CDATA[" + StrUtil.doNull(taskVo.getExecutionId(), "")
						+ "]]></executionId>");
				XmlStr.append("<assignee><![CDATA[" + StrUtil.doNull(taskVo.getAssignee(), "") + "]]></assignee>");
				XmlStr.append("<activityName><![CDATA[" + StrUtil.doNull(taskVo.getActivityName(), "")
						+ "]]></activityName>");
				XmlStr.append("<createDate><![CDATA[" + StrUtil.doNull(taskVo.getCreateDate(), "") + "]]></createDate>");
				XmlStr.append("<endDate><![CDATA[" + StrUtil.doNull(taskVo.getEndDate(), "") + "]]></endDate>");
				XmlStr.append("</record>");
			}
		}
		XmlStr.append("</records>");
		XmlStr.append("</root>");

		return XmlStr.toString();
	}

	/**
	 * 获取要返回的待办任务
	 * @param list
	 * @return
	 */
	private String getXmlDateList(String result, String errmsg, List list, Integer sumSize) {
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg><totalCount>" + sumSize
				+ "</totalCount>");
		XmlStr.append("<records totalRecord='" + (list == null ? 0 : list.size()) + "' >");

		if (null != list && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				TaskVo taskVo = (TaskVo) list.get(i);
				XmlStr.append("<record>");
				XmlStr.append("<taskId><![CDATA[" + StrUtil.doNull(taskVo.getId(), "") + "]]></taskId>");
				XmlStr.append("<processInstanceId><![CDATA[" + StrUtil.doNull(taskVo.getProcessInstanceId(), "")
						+ "]]></processInstanceId>");
				XmlStr.append("<taskName><![CDATA[" + StrUtil.doNull(taskVo.getName(), "") + "]]></taskName>");
				XmlStr.append("<formResourceUrl><![CDATA[" + StrUtil.doNull(taskVo.getFormResourceName(), "")
						+ "]]></formResourceUrl>");
				XmlStr.append("<createTime><![CDATA[" + StrUtil.doNull(taskVo.getCreateTime(), "") + "]]></createTime>");
				XmlStr.append("<userName><![CDATA[" + StrUtil.doNull(taskVo.getUserName(), "") + "]]></userName>");
				XmlStr.append("<assignee><![CDATA[" + StrUtil.doNull(taskVo.getAssignee(), "") + "]]></assignee>");
				XmlStr.append("<lastUser><![CDATA[" + StrUtil.doNull(taskVo.getLastUser(), "") + "]]></lastUser>");
				XmlStr.append("<endTime><![CDATA[" + StrUtil.doNull(taskVo.getEndTime(), "") + "]]></endTime>");
				XmlStr.append("<formId><![CDATA[" + StrUtil.doNull(taskVo.getFormId(), "") + "]]></formId>");
				XmlStr.append("<proId><![CDATA[" + StrUtil.doNull(taskVo.getProId(), "") + "]]></proId>");
				XmlStr.append("<proName><![CDATA[" + StrUtil.doNull(taskVo.getProName(), "") + "]]></proName>");
				XmlStr.append("<proNo><![CDATA[" + StrUtil.doNull(taskVo.getProNo(), "") + "]]></proNo>");
				//				XmlStr.append("<formDay>" +StrUtil.doNull(taskVo.getFormDay(),"")+ "</formDay>");
				//				XmlStr.append("<formPrice>" +StrUtil.doNull(taskVo.getFormPrice(),"")+ "</formPrice>");
				XmlStr.append("<sysEname><![CDATA[" + StrUtil.doNull(taskVo.getSysEname(), "") + "]]></sysEname>");
				XmlStr.append("<formType><![CDATA[" + StrUtil.doNull(taskVo.getFormType(), "") + "]]></formType>");
				XmlStr.append("<formName><![CDATA[" + StrUtil.doNull(taskVo.getFormName(), "") + "]]></formName>");
				XmlStr.append("<formInfo><![CDATA[" + StrUtil.doNull(taskVo.getFormInfo(), "") + "]]></formInfo>");
				XmlStr.append("</record>");
			}
		}
		XmlStr.append("</records>");
		XmlStr.append("</root>");

		return XmlStr.toString();
	}

	private String pageNo = "";
	private String pageSize = "";

	/**
	 * description:  历史任务查询
	 * @return  
	 * @author xyc 
	 * @update 2015-5-26
	 */
	public String getHisTaskByInfo() {
		logger.info("历史任务查询!");
		String result = "";
		String errmsg = "";
		String xml = "";
		String value = "";
		try {
			Map<String, String> variables = new HashMap<String, String>();
			Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
			while (names.hasMoreElements()) {
				String key = names.nextElement();
				String v = Struts2Utils.getRequest().getParameter(key);
				value = (null == v) ? "" : java.net.URLDecoder.decode(v, "UTF-8");
				variables.put(key, value);
			}
			if (StrUtil.isNull(pageNo)) {
				pageNo = "1";
			}
			if (StrUtil.isNull(pageSize)) {
				pageSize = "10";
			}
			FlowHistroy flowHistroy = new FlowHistroy();
			Page<FlowHistroy> page = flowHistoryManager.getHistoryByInfo(variables, Integer.parseInt(pageNo),
					Integer.parseInt(pageSize));

			List<FlowHistroy> taskVoList = page.getResult();
			result = "T";
			errmsg = "查询历史任务成功!";
			xml = getXmlHistTaskByInfo(result, errmsg, taskVoList, (int) page.getTotalCount());
			this.outputXml(xml, Struts2Utils.getResponse());
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * description:  历史任务查询出xml
	 * @param result
	 * @param errmsg
	 * @param list
	 * @param sumSize
	 * @return  
	 * @author xyc 
	 * @update 2015-5-26
	 */
	private String getXmlHistTaskByInfo(String result, String errmsg, List list, Integer sumSize) {
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg><totalCount>" + sumSize
				+ "</totalCount>");
		XmlStr.append("<records totalRecord='" + (list == null ? 0 : list.size()) + "' >");

		if (null != list && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				FlowHistroy taskVo = (FlowHistroy) list.get(i);
				XmlStr.append("<record>");
				XmlStr.append("<assignee><![CDATA[" + StrUtil.doNull(taskVo.getHisAssignee(), "") + "]]></assignee>");
				XmlStr.append("<createTime><![CDATA[" + StrUtil.doNull(taskVo.getHisCreateTime(), "")
						+ "]]></createTime>");
				XmlStr.append("<formDay><![CDATA[" + StrUtil.doNull(taskVo.getHisFormDay(), "") + "]]></formDay>");
				XmlStr.append("<formId><![CDATA[" + StrUtil.doNull(taskVo.getHisFormId(), "") + "]]></formId>");
				XmlStr.append("<formInfo><![CDATA[" + StrUtil.doNull(taskVo.getHisFormInfo(), "") + "]]></formInfo>");
				XmlStr.append("<formName><![CDATA[" + StrUtil.doNull(taskVo.getHisFormName(), "") + "]]></formName>");
				XmlStr.append("<formPrice><![CDATA[" + StrUtil.doNull(taskVo.getHisFormPrice(), "") + "]]></formPrice>");
				XmlStr.append("<formType><![CDATA[" + StrUtil.doNull(taskVo.getHisFormType(), "") + "]]></formType>");
				XmlStr.append("<hisId><![CDATA[" + StrUtil.doNull(taskVo.getHisId(), "") + "]]></hisId>");
				XmlStr.append("<nextUser><![CDATA[" + StrUtil.doNull(taskVo.getHisNextUser(), "") + "]]></nextUser>");
				XmlStr.append("<processinsId><![CDATA[" + StrUtil.doNull(taskVo.getHisProcessinsId(), "")
						+ "]]></processinsId>");
				XmlStr.append("<state><![CDATA[" + StrUtil.doNull(taskVo.getHisState(), "") + "]]></state>");
				XmlStr.append("<sysEname><![CDATA[" + StrUtil.doNull(taskVo.getHisSysEname(), "") + "]]></sysEname>");
				XmlStr.append("<taskId><![CDATA[" + StrUtil.doNull(taskVo.getHisTaskId(), "") + "]]></taskId>");
				XmlStr.append("<taskName><![CDATA[" + StrUtil.doNull(taskVo.getHisTaskName(), "") + "]]></taskName>");
				XmlStr.append("<userName><![CDATA[" + StrUtil.doNull(taskVo.getHisUserName(), "") + "]]></userName>");
				XmlStr.append("</record>");
			}
		}
		XmlStr.append("</records>");
		XmlStr.append("</root>");

		return XmlStr.toString();
	}

	/**
	 * description:  获取历史待办任务
	 * @return  
	 * @author xyc 
	 * @throws Exception 
	 * @update 2015-4-14
	 */
	public String tranHistTask() throws Exception {
		logger.info("综合历史待办任务开始 ");
		String result = null;
		String errmsg = null;
		String xml = null;
		Map<String, String> variables = new HashMap<String, String>();
		Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
		while (names.hasMoreElements()) {
			String key = names.nextElement();
			String v = Struts2Utils.getRequest().getParameter(key);
			String value = (null == v) ? "" : java.net.URLDecoder.decode(v, "UTF-8");
			variables.put(key, value);
		}
		try {

			Page<Object[]> page = flowDeployManager.findHistTasksByOptions(variables);

			List<HistTaskVo> taskVoList = new ArrayList<HistTaskVo>();
			String description = null;
			String[] strs = null;
			for (Object[] objArry : page.getResult()) {
				HistTaskVo taskVo = new HistTaskVo();
				taskVo.setAssignee(objArry[3] + "");
				taskVo.setActivityName(objArry[2] + "");
				taskVo.setCreateDate(objArry[4] + "");
				taskVo.setEndDate(objArry[5] + "");
				taskVo.setExecutionId(objArry[1] + "");
				taskVo.setProcdefId(objArry[0] + "");
				taskVoList.add(taskVo);
			}
			result = "T";
			errmsg = "综合历史待办任务成功";
			xml = getXmlHistTaskList(result, errmsg, taskVoList, (int) page.getTotalCount());
		} catch (Exception e) {
			result = "F";
			errmsg = "发生未知异常";
			xml = getXmlDateList(result, errmsg, null, 0);
			e.printStackTrace();
		}

		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	/**
	 * 
	 * @return
	 * <p>@description 动态扭转
	 * <p>@version 1.0
	 * <p>@author lvcai
	 * <p>@update 2013-10-31 上午09:57:22
	 * @throws Exception 
	 */
	@Transactional
	public String dynamicallyTransition() throws Exception {
		logger.info("动态扭转方法开始 ");
		String result = "F";
		String errmsg = "操作失败";
		if (StrUtil.isNotNull(processInsId)) {

			//校验当前活动节点是不是自处理任务节点
			List<Task> autoTaskList = this.getActExecutionTask();
			if (null != autoTaskList && autoTaskList.size() == 1) {
				Task task = autoTaskList.get(0);
				String taskIdTemp = task.getId();
				//任务表删除任务
				FlowAutomaticProcessing flowAutomaticProcessing = automaticProcessingManager
						.getAutomaticProcessingByNodeId(taskIdTemp);
				if (flowAutomaticProcessing != null) {
					automaticProcessingManager.deleteAutomaticProcessing(flowAutomaticProcessing);
				}
				logger.info("删除自处理任务成功,taskId为：" + taskIdTemp);
			}

			//管理流程实例
			ExecutionService executionService = processEngine.getExecutionService();
			//流程实例
			ProcessInstance processInstance = executionService.findProcessInstanceById(processInsId);
			if (processInstance != null) {
				if ("suspended".equals(processInstance.getState())) {
					result = "F";
					errmsg = "该流程实例已挂起";

				} else {
					if (StrUtil.isNotNull(sourceNode)) {
						TaskService taskService = processEngine.getTaskService();
						TaskQuery taskQuery = taskService.createTaskQuery();
						List<Task> taskList = taskQuery.processInstanceId(processInsId).list();
						if (taskList == null || taskList.size() == 0) { //2016-03-07 &&-->||
							result = "F";
							errmsg = "未找到当前活动的Task任务";
						} else if (taskList.size() == 1) {
							String createTransitionName = "to " + sourceNode.trim();
							Task activeTask = taskList.get(0);
							EnvironmentImpl envImpl = ((EnvironmentFactory) processEngine).openEnvironment();

							ExecutionImpl e = (ExecutionImpl) executionService.findExecutionById(activeTask
									.getExecutionId());
							ActivityImpl clerkOpinionActivityImpl = e.getActivity();

							ProcessDefinitionImpl processDefinitionImpl = clerkOpinionActivityImpl
									.getProcessDefinition();

							ActivityImpl applyActivityImpl = processDefinitionImpl.findActivity(sourceNode.trim());
							if (applyActivityImpl != null) {//能够查询到目标节点
								TransitionImpl toApply = clerkOpinionActivityImpl.createOutgoingTransition();
								toApply.setSource(clerkOpinionActivityImpl);
								toApply.setDestination(applyActivityImpl);
								toApply.setName(createTransitionName);
								taskService.completeTask(activeTask.getId(), createTransitionName);
								result = "T";
								errmsg = "动态流转成功";
							} else {//目标节点不存在
								result = "F";
								errmsg = "流程流转的目标节点不存在";
							}
							if (envImpl != null) {
								envImpl.close();
							}

						} else {
							result = "F";
							errmsg = "当前活动的Task个数大于1,暂不支持动态流转";
						}
					} else {
						result = "F";
						errmsg = "目标节点参数未传递";
					}
				}
			} else {
				result = "F";
				errmsg = "该流程实例不存在或者已结束";
			}

		} else {
			errmsg = "参数processInsId为空";
		}
		String xml = getResultXml(result, errmsg, null);
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	/**
	 * description: 结束流程等待状态 
	 */
	public String overState() throws IOException {
		logger.info("结束流程等待状态方法开始[processInsId=" + processInsId + "]");
		String xml = null;

		Map<String, String> variables = new HashMap<String, String>();
		Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
		while (names.hasMoreElements()) {
			String key = names.nextElement();
			if (null != key && !"".equals(key)) {
				String value = Struts2Utils.getRequest().getParameter(key);
				variables.put(key, java.net.URLDecoder.decode(value, "UTF-8"));
			}
		}

		ExecutionService executionService = processEngine.getExecutionService();
		//executionService.setVariables(processInsId, variables);

		//校验当前活动节点是不是state节点
		List<Task> taskList = this.getActExecutionTask();
		if (null != taskList && taskList.size() > 0) {
			this.logger.info("当前活动节点不是state节点！");
			xml = getResultXml("F", "当前活动节点不是state节点！", processInsId);
			this.outputXml(xml, Struts2Utils.getResponse());
			return null;
		}

		//结束当前节点
		String signalTransName = variables.get("signalTransName");
		try {
			if (StrUtil.isNull(signalTransName)) {
				executionService.signalExecutionById(processInsId, variables);
			} else {
				logger.info("---transitionName=" + signalTransName);
				executionService.signalExecutionById(processInsId, signalTransName, variables);
			}
		} catch (Exception e) {
			xml = getResultXml("F", "error,发生未知异常", processInsId);
			logger.info("error,发生未知异常:" + e.getMessage());
			this.outputXml(xml, Struts2Utils.getResponse());
			return null;
		}

		xml = getResultXml("T", "结束流程等待状态成功", processInsId);
		logger.info("流结束流程等待状态成功，报文：" + xml);
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	/**
	 * description:  根据实例id查询当前活动节点任务[父任务及子任务](processInsId)
	 * @update 2015-12-6
	 */
	public List<Task> getActExecutionTask() {
		//根据实例id查询当前活动节点任务
		ExecutionService executionService = processEngine.getExecutionService();
		ProcessInstance processInstance = executionService.createProcessInstanceQuery().processInstanceId(processInsId)
				.uniqueResult();
		Set<String> nameSet = processInstance.findActiveActivityNames(); //节点名称
		String name = null;
		Iterator<String> it = nameSet.iterator();
		if (StrUtil.isNotNull(findNodeName)) {//指定节点name
			name = findNodeName.trim();
		} else if (it.hasNext()) {
			name = it.next();//第一个活动节点name
		} else {
			return null;
		}
		Execution execution = processInstance.findActiveExecutionIn(name);
		TaskService taskService = processEngine.getTaskService();
		List<Task> taskList = taskService.createTaskQuery().executionId(execution.getId()).list();
		return taskList;
	}

	/**
	 * description:执行定时任务  
	 * @update 2016-1-15
	 */
	public String doAutoTask() {
		logger.info("----------------执行定时任务开始!");
		String xml = null;
		try {
			AutoTaskTimer.getInstance().run();
		} catch (Exception e) {
			this.logger.error("--------执行定时任务错误：" + e.getMessage());
			//e.printStackTrace();
			xml = getResultXml("F", "执行定时任务错误失败！", "");
			this.outputXml(xml, Struts2Utils.getResponse());
			return null;
		}

		xml = getResultXml("T", "执行定时任务成功！", "");
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	/**
	 * description:  查询自处理任务信息
	 * param:taskId
	 * 20151205
	 */
	public String getAotoProcessingInfo() {
		logger.info("查询自处理任务信息方法开始[processInsId=" + processInsId + "]");
		List<Task> taskList = this.getActExecutionTask();
		String xml = null;
		String taskId = null;
		if (null == taskList || taskList.size() == 0) {
			this.logger.info("当前活动节点未查询到任务！");
			xml = this.getXmlAotoProcessingInfo("F", "当前活动节点未查询到任务！", null);
		} else if (taskList.size() > 1) {
			this.logger.info("当前活动节点有多条任务，此节点非自处理任务节点！");
			xml = this.getXmlAotoProcessingInfo("F", "当前活动节点有多条任务，此阶段非自处理任务节点！", null);
		} else {
			taskId = taskList.get(0).getId();//
			if (StrUtil.isNotNull(taskId)) {
				try {
					FlowAutomaticProcessing processing = new FlowAutomaticProcessing();
					processing = automaticProcessingManager.getAutomaticProcessingByNodeId(taskId);
					if (null != processing) {
						xml = this.getXmlAotoProcessingInfo("T", "根据taskId查询自处理任务信息成功！", processing);
						this.logger.info("根据taskId查询自处理任务信息成功！");
					} else {
						xml = this.getXmlAotoProcessingInfo("F", "根据taskId查询自处理任务信息失败！", null);
						this.logger.info("根据taskId查询自处理任务信息失败！");
					}
				} catch (Exception e) {
					xml = this.getXmlAotoProcessingInfo("F", "根据taskId查询自处理任务信息发生异常！", null);
					this.logger.info("根据taskId查询自处理任务信息发生异常！");
					e.printStackTrace();
				}
			} else {
				xml = this.getXmlAotoProcessingInfo("F", "参数taskId不能为空！", null);
				this.logger.info("参数taskId不能为空！");
			}
		}
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	public String updateMapInfo() throws IOException {
		logger.info("更新map信息方法[updateMapInfo]开始[processInsId=" + processInsId + "]");
		String xml = null;
		Map<String, String> variables = new HashMap<String, String>();
		Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
		while (names.hasMoreElements()) {
			String key = names.nextElement();
			if (key.equals("processInsId") || key.equals("definitionId"))
				continue;
			if (null != key && !"".equals(key)) {
				String value = Struts2Utils.getRequest().getParameter(key);
				variables.put(key, java.net.URLDecoder.decode(value, "UTF-8"));
			}
		}
		if (StrUtil.isNotNull(processInsId)) {
			if (variables.size() == 0) {
				xml = getResultXml("F", "更新map信息失败，要更新的参数为空！", processInsId);
				this.outputXml(xml, Struts2Utils.getResponse());
				return null;
			}
			ExecutionService executionService = processEngine.getExecutionService();
			executionService.setVariables(processInsId, variables);
			xml = getResultXml("T", "更新map信息成功！", processInsId);

		} else {
			xml = getResultXml("F", "更新map信息失败，processInsId参数为空！", "");
		}
		this.outputXml(xml, Struts2Utils.getResponse());
		return null;
	}

	private String getXmlAotoProcessingInfo(String result, String errmsg, FlowAutomaticProcessing flowAuto) {
		StringBuffer XmlStr = new StringBuffer("<?xml version='1.0' encoding='UTF-8'?><root>");
		XmlStr.append("<result>" + result + "</result><errmsg>" + errmsg + "</errmsg>");
		if (null != flowAuto) {
			XmlStr.append("<dbId><![CDATA[" + StrUtil.doNull(flowAuto.getDbId(), "") + "]]></dbId>");
			XmlStr.append("<taskId><![CDATA[" + StrUtil.doNull(flowAuto.getTaskId(), "") + "]]></taskId>");
			XmlStr.append("<handleUrl><![CDATA[" + StrUtil.doNull(flowAuto.getHandleUrl(), "") + "]]></handleUrl>");
			XmlStr.append("<handleStauts><![CDATA[" + StrUtil.doNull(flowAuto.getHandleStauts(), "")
					+ "]]></handleStauts>");
			XmlStr.append("<handleParam><![CDATA[" + StrUtil.doNull(flowAuto.getHandleParam(), "")
					+ "]]></handleParam>");
			XmlStr.append("<processInsId><![CDATA[" + StrUtil.doNull(flowAuto.getProcessInsId(), "")
					+ "]]></processInsId>");
			XmlStr.append("<createTime><![CDATA[" + StrUtil.doNull(flowAuto.getCreateTime(), "") + "]]></createTime>");
			XmlStr.append("<executeInfo><![CDATA[" + StrUtil.doNull(flowAuto.getExecuteInfo(), "")
					+ "]]></executeInfo>");
			XmlStr.append("<executeTime><![CDATA[" + StrUtil.doNull(flowAuto.getExecuteTime(), "")
					+ "]]></executeTime>");
		}
		XmlStr.append("</root>");
		return XmlStr.toString();

	}

	/**
	 * 输出客户端信息
	 * @param xml
	 * @param response
	 */
	private void outputXml(String xml, HttpServletResponse response) {
		try {
			response.setContentType("text/xml; charset=UTF-8");
			PrintWriter out = response.getWriter();
			out.print(xml);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public String getAgentUserId() {
		return agentUserId;
	}

	public void setAgentUserId(String agentUserId) {
		this.agentUserId = agentUserId;
	}

	public String getDefinitionId() {
		return definitionId;
	}

	public void setDefinitionId(String definitionId) {
		this.definitionId = definitionId;
	}

	public ProcessEngine getProcessEngine() {
		return processEngine;
	}

	public void setProcessEngine(ProcessEngine processEngine) {
		this.processEngine = processEngine;
	}

	public ActivityCoordinates getAc() {
		return ac;
	}

	public void setAc(ActivityCoordinates ac) {
		this.ac = ac;
	}

	public String getProcessInsId() {
		return processInsId;
	}

	public void setProcessInsId(String processInsId) {
		this.processInsId = processInsId;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	public String getOp() {
		return op;
	}

	public void setOp(String op) {
		this.op = op;
	}

	public String getStartNode() {
		return startNode;
	}

	public void setStartNode(String startNode) {
		this.startNode = startNode;
	}

	public String getSourceNode() {
		return sourceNode;
	}

	public void setSourceNode(String sourceNode) {
		this.sourceNode = sourceNode;
	}

	public String getPageNo() {
		return pageNo;
	}

	public void setPageNo(String pageNo) {
		this.pageNo = pageNo;
	}

	public String getPageSize() {
		return pageSize;
	}

	public void setPageSize(String pageSize) {
		this.pageSize = pageSize;
	}

	public void setFlowDeployManager(FlowDeployManager flowDeployManager) {
		this.flowDeployManager = flowDeployManager;
	}

	public FlowDeployManager getFlowDeployManager() {
		return flowDeployManager;
	}

	public void setFlowHistoryManager(FlowHistoryManager flowHistoryManager) {
		this.flowHistoryManager = flowHistoryManager;
	}

	public void setAutomaticProcessingManager(FlowAutomaticProcessingManager automaticProcessingManager) {
		this.automaticProcessingManager = automaticProcessingManager;
	}

	public String getFindNodeName() {
		return findNodeName;
	}

	public void setFindNodeName(String findNodeName) {
		this.findNodeName = findNodeName;
	}

	public String getProId() {
		return proId;
	}

	public void setProId(String proId) {
		this.proId = proId;
	}

}
